/*
   Copyright 2009 - Morten Udnæs

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */

package com.javabatch.petstore.fixtures;

import java.text.DecimalFormat;
import java.util.Random;

import com.javabatch.fileio.FileBuffer;
import com.javabatch.fileio.FileStore;
import com.javabatch.fileio.RecordBasedFileStore;
import com.javabatch.petstore.process.CreateInvoiceProcess;
import com.javabatch.petstore.records.CustomerRecord;
import com.javabatch.petstore.records.OrderRecord;

/**
 * Simple file generator for use with fitnesse.
 * 
 * @author Morten Udnæs
 */
public class CreateBigFileFixture {
	private static final int ANIMAL_CATALOG_SIZE = 83874;
	private FileStore customerStore;
	private FileStore orderStore;
	private double executionTimeInMilliseconds;
	private DecimalFormat rounded = new DecimalFormat("#0.00");
	private long ordersProcessed;
	private long customersProcessed;
	private String[] customerNames = new String[] { "Donald", "Dolly", "Ole", "Dole", "Doffen", "Anton", "Skrue",
			"Rikerud", "Langbein", "Mikke" };


	public CreateBigFileFixture(String catalogFile, String customerFile, String orderFile) {
		customerStore = new RecordBasedFileStore(customerFile, RecordBasedFileStore.WRITE_ACCESS, CustomerRecord
				.getLengthAndValidateRecord());
		orderStore = new RecordBasedFileStore(orderFile, RecordBasedFileStore.WRITE_ACCESS, OrderRecord
				.getLengthAndValidateRecord());
	}

	// Collections.sort, sorter i minne. Leser inn chunker av data fra orders
	// usortert
	
	public boolean createCustomersAndOrders(String customers, String orders) {
		long startTime = System.currentTimeMillis();
		Random rnd = new Random();
		Integer customerId = 0;
		Integer orderId = 0;

		customerStore.open();
		orderStore.open();

		for (int i = 0; i < Integer.parseInt(customers); i++) {
			customerId++;
			FileBuffer customerBuffer = new FileBuffer();
			
			CustomerRecord.CUSTOMER_ID.write(customerBuffer, customerId.toString());
			CustomerRecord.CUSTOMER_NAME.write(customerBuffer, customerNames[rnd.nextInt(customerNames.length)] + "_" + customerId.toString());
			CustomerRecord.CUSTOMER_ADDRESS.write(customerBuffer, "Town_" + customerId.toString());
			CustomerRecord.CUSTOMER_POSTAL_CODE.write(customerBuffer, "3321");
			
			customerStore.write(customerBuffer);

			// 50% customer haven't shopped
			if (rnd.nextInt(100) < 10) {
				customersProcessed++;
				Integer animalId = rnd.nextInt(ANIMAL_CATALOG_SIZE)+1;
				Integer items = rnd.nextInt(50);

				for (int o = 0; o < Integer.parseInt(orders); o++) {
					orderId++;
					FileBuffer orderBuffer = new FileBuffer();

					OrderRecord.ORDER_ID.write(orderBuffer, orderId.toString());
					OrderRecord.CUSTOMER_ID.write(orderBuffer, customerId.toString());
					OrderRecord.CATALOG_ID.write(orderBuffer, animalId.toString());
					OrderRecord.ITEMS.write(orderBuffer, items.toString());
					orderStore.write(orderBuffer);
				}
			}
		}

		orderStore.close();
		customerStore.close();

		ordersProcessed = orderId;
		
		executionTimeInMilliseconds = (System.currentTimeMillis() - startTime);
		return true;
	}

	public String executionTime() {

		double secs = executionTimeInMilliseconds/1000;
		return rounded.format(secs) + " seconds";
	}
	
	public String throughput() {
		return ordersProcessed + " records processed";
	}
	
	public String recordsPrSecond() {
		double recprSec = ordersProcessed*1000 / executionTimeInMilliseconds;
		return rounded.format(recprSec) + " recs/sec";
	}
	
	public String customersWithOrders() {
		return Long.toString(customersProcessed);
	}
}
